﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.IO.Compression;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace DS2171Utils
{
    public class ZipDati
    {
         public FileInfo  Compress(FileInfo fi)
        {
             string tempFile = string.Empty ;

             using (FileStream inFile = fi.OpenRead())
            {
                // Prevent compressing hidden and  already compressed files.
                if ((File.GetAttributes(fi.FullName) 
                	& FileAttributes.Hidden)!= FileAttributes.Hidden & fi.Extension != ".gz")
                {

                    var tempDirPath = Path.Combine(Environment.CurrentDirectory, "TempFiles");
                    if (!Directory.Exists(tempDirPath)) Directory.CreateDirectory(tempDirPath);

                    tempFile = Path.Combine(tempDirPath, fi.Name + ".gz");

                    // Create the compressed file.
                    using (FileStream outFile = File.Create(tempFile))
                    {
                        using (GZipStream Compress = new GZipStream(outFile, CompressionMode.Compress))
                        {
                            // Copy the source file into the compression stream.
                            inFile.CopyTo(Compress);
                            //return string.Format("Compressed {0} from {1} to {2} bytes.",
                            //  fi.Name, fi.Length.ToString(), outFile.Length.ToString());
                        }
                    }
                }
            }
             if (File.Exists(tempFile))
                 return new FileInfo(tempFile);
             else
                 return null;

        }//fM


         public byte[] CompressInMemory(FileInfo fi)
         {
             byte[] byteArray = null;
             using (FileStream inFile = fi.OpenRead())
             {
                 // Prevent compressing hidden and 
                 // already compressed files.
                 if ((File.GetAttributes(fi.FullName)
                     & FileAttributes.Hidden) != FileAttributes.Hidden & fi.Extension != ".gz")
                 {

                     var tempDirPath = Path.Combine(Environment.CurrentDirectory, "TempFiles");
                     if (!Directory.Exists(tempDirPath)) Directory.CreateDirectory(tempDirPath);

                     var tempFile = Path.Combine(tempDirPath, fi.Name + ".gz");

                     // Create the compressed file.
                     using (var mes = new MemoryStream())
                     {
                         using (GZipStream Compress =new GZipStream(mes, CompressionMode.Compress))
                         {
                             // Copy the source file into the compression stream.
                             inFile.CopyTo(Compress);
                             mes.Seek(0, SeekOrigin.Begin);
                             byteArray = new byte[mes.Length];
                             var count = mes.Read(byteArray, 0, (int)mes.Length);

                             //return string.Format("Compressed {0} from {1} to {2} bytes.",
                             //  fi.Name, fi.Length.ToString(), outFile.Length.ToString());
                         }                        
                     }
                 }
             }

             return byteArray;

         }//fM


         public byte[] CompressInMemory(byte[] pDati)
         {
             
             byte[] byteArray = null;
                            
                    // Create the compressed file.
                     using (var mes = new MemoryStream())
                     {
                         using (GZipStream Compress = new GZipStream(mes, CompressionMode.Compress,true))
                         {                                
                             // Copy the source file into the compression stream.
                             Compress.Write(pDati,0,pDati.Length);
                             Compress.Flush(); 
                         }

                         byteArray = mes.ToArray(); 
                     }           

             return byteArray;

         }//fM



         public void scriviZipStreamInFile(FileInfo fi,GZipStream pDatiCompressi)
        {
            using (FileStream inFile = fi.OpenRead())
            {
                pDatiCompressi.CopyTo(inFile);
            }
        
        }//fM

         public string levaEstensionedaFile(string pFileName,string pEstensioneDaLevare)
         {
             return "";       
         }//fM

         public void Decompress(byte[] pDatiCompressi, string pPathDirToDecompress, string pFileName)
         {
             // Get the stream of the source file.
             using (MemoryStream inFile = new MemoryStream(pDatiCompressi))
             {
                 var tempFile = Path.Combine(pPathDirToDecompress, pFileName);
                 //Create the decompressed file.
                 using (FileStream outFile = File.Create(tempFile))
                 {
                     using (GZipStream Decompress = new GZipStream(inFile,CompressionMode.Decompress))
                     {
                         // Copy the decompression stream  into the output file.
                         Decompress.CopyTo(outFile);
                     }
                 }
             }
         }//fM


         public FileInfo Decompress(byte[] pDatiCompressi, string pPathFileToDecompress)
         {             
             // Get the stream of the source file.
             using (MemoryStream inFile = new MemoryStream(pDatiCompressi))
             {                
                 //Create the decompressed file.
                 using (FileStream outFile = File.Create(pPathFileToDecompress))
                 {
                     using (GZipStream Decompress = new GZipStream(inFile, CompressionMode.Decompress))
                     {                         // Copy the decompression stream  into the output file.
                         Decompress.CopyTo(outFile);
                     }
                 }
             }

             return (new FileInfo(pPathFileToDecompress));    

         }//fM


         public byte[] Decompress(byte[] pGzipData, int pLunghezzaOriginaria)
         {
             byte[] arrBytes = null;
             //DeCompress
             using (var decomStream = new MemoryStream(pGzipData)) //cmpData
             {                
                 using (var hgs = new GZipStream(decomStream, CompressionMode.Decompress, true))
                 {

                     byte[] step = new byte[16]; //Instead of 16 can put any 2^x
                     using (var outStream = new MemoryStream())
                     {
                         int readCount;
                         hgs.CopyTo(outStream);

                         do
                         {
                             readCount = hgs.Read(step, 0, step.Length);
                             outStream.Write(step, 0, readCount);
                         } while (readCount > 0);

                         arrBytes = outStream.ToArray();  

                     }
                     hgs.Close();
                 }
 
             }

             //test
             //string sampleOut = new System.Text.ASCIIEncoding().GetString(arrBytes);
             
             return arrBytes;
             //

             using (GZipStream stream = new GZipStream(new MemoryStream(pGzipData), CompressionMode.Decompress))
             {
                 int size = (pGzipData.Length < 4096 )? pGzipData.Length:4096;
                 byte[] buffer = new byte[size];
                 using (MemoryStream memory = new MemoryStream())
                 {
                     int count = 0;
                       
                     do
                     {
                         count = stream.Read(buffer, 0, size);
                         stream.Flush();  
                         if (count > 0)
                         {
                             memory.Write(buffer, 0, count);
                         }
                     }
                     while (count > 0);
                     return memory.ToArray();
                 }
             }
         }

        

         public  byte[] ReadFileFromPath(string sPath)
         {
             if (string.IsNullOrEmpty(sPath)) return null;

             //Initialize byte array with a null value initially.
             byte[] data = null;

             //Use FileInfo object to get file size.
             FileInfo fInfo = new FileInfo(sPath);
             long numBytes = fInfo.Length;

             //Open FileStream to read file
             using (var fStream = new FileStream(sPath, FileMode.Open,FileAccess.Read))
             {
                 //Use BinaryReader to read file stream into byte array.
                 using (var br = new BinaryReader(fStream))
                 {
                     //So supplying total number of bytes.
                     data = br.ReadBytes((int)numBytes);
                     br.Close();
                 }
             }

             return data;


         }//fM

         public void SaveBytesInFile(string sPath, byte[] pData)
         {
             if (string.IsNullOrEmpty(sPath)) return;
             if (pData == null || pData.Length == 0) return;

             using (var fStream = File.Create(sPath, pData.Length, FileOptions.None))
             {
                 using (var br = new BinaryWriter(fStream))
                 {
                     br.Write(pData);
                 }
             }

         }//fM



         public bool Test(byte[] pDati)
         {
             System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
             var data = pDati;
             bool result = false;

             // Compress 
             MemoryStream cmpStream = new MemoryStream();
             GZipStream hgs = new GZipStream(cmpStream, CompressionMode.Compress, true);

             hgs.Write(data, 0, data.Length);
             hgs.Close();


             //DeCompress
             byte[] cmpData = cmpStream.ToArray();
             MemoryStream decomStream = new MemoryStream(cmpData);

             data = new byte[cmpStream.Length * 5]; //byte[data.Length];
             hgs = new GZipStream(decomStream, CompressionMode.Decompress, true);

             byte[] step = new byte[16]; //Instead of 16 can put any 2^x
             MemoryStream outStream = new MemoryStream();
             int readCount;

             do
             {
                 readCount = hgs.Read(step, 0, step.Length);
                 outStream.Write(step, 0, readCount);
             } while (readCount > 0);
             hgs.Close();

             var ok = pDati.Equals(outStream); 

             string sampleOut = encoding.GetString(outStream.ToArray());
             string sample1 = encoding.GetString(pDati);

             result = String.Equals(sample1, sampleOut);
             return result;
         }

    }//fC


    }//fN

